场景如下:
前端vue使用axios向后台发了一个Content-type为application/json的post请求,
后台springmvc接口如下:

@RequestMapping("xxx")
public Result xxx(User user) {
    Result result = Result.getSuccessResult();
    return  result;
}

发现接收不到user的信息。
改为 request.getParamter 也一样接收不到。
搜索一番,从这篇博客找到了答案
AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

jquery在执行post请求时,会设置Content-Type为application/x-www-form-urlencoded,所以服务器能够正确解析,而使用原生ajax请求时,如果不显示的设置Content-Type,那么默认是text/plain,这时服务器就不知道怎么解析数据了,所以才只能通过获取原始数据流的方式来进行解析请求数据。
HTTP POST表单请求提交时,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST请求如果不指定请求头RequestHeader,默认使用的Content-Type是text/plain;charset=UTF-8。
由于Tomcat对于Content-Type multipart/form-data(文件上传)和application/x-www-form-urlencoded(POST请求)做了“特殊处理”。
服务器为什么会对表单提交和文件上传做特殊处理,是因为表单提交数据是名值对的方式,且Content-Type为application/x-www-form-urlencoded,而文件上传服务器需要特殊处理,普通的post请求(Content-Type不是application/x-www-form-urlencoded)数据格式不固定,不一定是名值对的方式,所以服务器无法知道具体的处理方式,所以只能通过获取原始数据流的方式来进行解析。

总结为:原生ajax如果不指定Context-type默认使用text/plain;charset=UTF-8,jquery的ajax则是application/x-www-form-urlencoded,而axios底层正是使用了原生的ajax,后端会对非Content-type不为application/x-www-form-urlencoded的请求做特殊处理,由此导致后端request.getParameter()无法接收。


解决方法
1、不使用框架的情况下,使用原始的读取流的方式:

 private String getRequestPayload(HttpServletRequest req) {
   StringBuildersb = new StringBuilder();
   try(BufferedReaderreader = req.getReader();) {
        char[]buff = new char[1024];
        intlen;
        while((len = reader.read(buff)) != -1) {
                 sb.append(buff,0, len);
        }
   }catch (IOException e) {
        e.printStackTrace();
   }
   returnsb.toString();
 }

2、使用spring框架:
加入@RequestBody注解,如下:

@RequestMapping("xxx")
public Result xxx(@RequestBody User user) {
    Result result = Result.getSuccessResult();
    return  result;
}

瓦力
575 声望15 粉丝

一只coder